package test.searcher;

import jade.core.AID;
import jade.core.Agent;
import jade.domain.FIPANames;
import jade.lang.acl.ACLMessage;
import test.BaseCommunicationTestBehaviour;
import de.fhin.mas.MASEvents;
import de.fhin.mas.ontology.Location;
import de.fhin.mas.ontology.SearchableObject;
import de.fhin.mas.util.MessageUtil;

/**
 * Dieses <tt>Behaviour</tt> enthält einige nützliche Methoden für die
 * Sucher-Tests.
 * 
 * @author Alexander Weickmann
 */
public abstract class SearcherTestBehaviour extends
		BaseCommunicationTestBehaviour {

	/** Die eindeutige ID zur Serialisierung ueber das Netzwerk. */
	private static final long serialVersionUID = -7236488793572142676L;

	/**
	 * Erzeugt das <tt>SearcherTestBehaviour</tt>.
	 * 
	 * @param parent
	 *            Der Test-Agent, zu dem das <tt>Behaviour</tt> gehoert.
	 */
	protected SearcherTestBehaviour(Agent parent) {
		super(parent);
	}

	/**
	 * Wartet auf ein <tt>target_search_started</tt>, gibt <tt>true</tt>
	 * zurück, falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForTargetSearchStarted() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.TARGET_SEARCH_STARTED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), DEFAULT_RESPONSE_TIME) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Wartet auf ein <tt>environment_scan_started</tt>, gibt <tt>true</tt>
	 * zurück, falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForEnvironmentScanStarted() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.ENVIRONMENT_SCAN_STARTED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), DEFAULT_RESPONSE_TIME) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Wartet auf ein <tt>environment_scan_canceled</tt>, gibt <tt>true</tt>
	 * zurück, falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForEnvironmentScanCanceled() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.ENVIRONMENT_SCAN_CANCELED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), DEFAULT_RESPONSE_TIME) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Wartet auf ein <tt>target_search_canceled</tt>, gibt <tt>true</tt>
	 * zurück, falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForTargetSearchCanceled() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.TARGET_SEARCH_CANCELED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), 5000) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Wartet auf ein <tt>target_search_paused</tt>, gibt <tt>true</tt> zurück,
	 * falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForTargetSearchPaused() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.TARGET_SEARCH_PAUSED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), 5000) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Wartet auf ein <tt>target_search_resumed</tt>, gibt <tt>true</tt>
	 * zurück, falls empfangen, <tt>false</tt> falls nicht.
	 */
	protected boolean waitForTargetSearchResumed() {
		if (myAgent.blockingReceive(MessageUtil
				.buildBasicCommunicationTemplate(null,
						MASEvents.TARGET_SEARCH_RESUMED.getName(),
						ACLMessage.INFORM, ((SearcherTestAgent) myAgent)
								.getAgentToTest()), DEFAULT_RESPONSE_TIME) == null) {
			return false;
		}

		return true;
	}

	/**
	 * Sendet das <tt>INFORM-DONE</tt> des Navigators auf einen
	 * <tt>system_stop_required</tt> - <tt>REQUEST</tt>.
	 */
	protected void sendNavigatorSystemStopRequiredInformDone() {
		buildAndSendMessage(FIPANames.InteractionProtocol.FIPA_REQUEST,
				MASEvents.SYSTEM_STOP_REQUIRED.getName(), ACLMessage.INFORM,
				new AID[] { ((SearcherTestAgent) myAgent).getAgentToTest() });
	}

	/**
	 * Sendet ein <tt>new_order</tt> - <tt>CFP</tt> und kurz danach ein
	 * <tt>new_order</tt> - <tt>ACCEPT-PROPOSAL</tt>.
	 */
	protected void sendNewOrderCfpAndAcceptProposal() {
		buildAndSendNewOrderCFPMessage(
				new AID[] { ((SearcherTestAgent) myAgent).getAgentToTest() },
				new SearchableObject("Wuerfel", "black", "cubic", 10, 10, 10),
				new Location("stor1", 123, 456, 3));
		doWait(1000);
		buildAndSendMessage(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET,
				MASEvents.NEW_ORDER.getName(), ACLMessage.ACCEPT_PROPOSAL,
				new AID[] { ((SearcherTestAgent) myAgent).getAgentToTest() });
	}

	/**
	 * Sendet ein <tt>movement_of_platform</tt> - <tt>CFP</tt> und kurz danach
	 * ein <tt>movement_of_platform</tt> - <tt>ACCEPT-PROPOSAL</tt>.
	 */
	protected void sendMovementOfPlatformNecessaryCfpAndAcceptProposal() {
		buildAndSendMessage(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET,
				MASEvents.MOVEMENT_OF_PLATFORM_NECESSARY.getName(),
				ACLMessage.CFP, new AID[] { ((SearcherTestAgent) myAgent)
						.getAgentToTest() });
		doWait(1000);
		buildAndSendMessage(FIPANames.InteractionProtocol.FIPA_CONTRACT_NET,
				MASEvents.MOVEMENT_OF_PLATFORM_NECESSARY.getName(),
				ACLMessage.ACCEPT_PROPOSAL,
				new AID[] { ((SearcherTestAgent) myAgent).getAgentToTest() });
	}

	/** Sendet ein <tt>system_stop_required</tt> - <tt>REQUEST</tt>. */
	protected void sendSystemStopRequiredRequest() {
		buildAndSendMessage(FIPANames.InteractionProtocol.FIPA_REQUEST,
				MASEvents.SYSTEM_STOP_REQUIRED.getName(), ACLMessage.REQUEST,
				new AID[] { ((SearcherTestAgent) myAgent).getAgentToTest() });
	}

}
